/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dao;

import dao.exceptions.NonexistentEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import ecfdb.Depot;
import java.util.ArrayList;
import java.util.List;
import ecfdb.CreditFellah;
import ecfdb.Fellah;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author QEMLAB
 */
public class FellahJpaController implements Serializable {

    public FellahJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Fellah fellah) {
        if (fellah.getDepotList() == null) {
            fellah.setDepotList(new ArrayList<Depot>());
        }
        if (fellah.getCreditFellahList() == null) {
            fellah.setCreditFellahList(new ArrayList<CreditFellah>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<Depot> attachedDepotList = new ArrayList<Depot>();
            for (Depot depotListDepotToAttach : fellah.getDepotList()) {
                depotListDepotToAttach = em.getReference(depotListDepotToAttach.getClass(), depotListDepotToAttach.getIddepot());
                attachedDepotList.add(depotListDepotToAttach);
            }
            fellah.setDepotList(attachedDepotList);
            List<CreditFellah> attachedCreditFellahList = new ArrayList<CreditFellah>();
            for (CreditFellah creditFellahListCreditFellahToAttach : fellah.getCreditFellahList()) {
                creditFellahListCreditFellahToAttach = em.getReference(creditFellahListCreditFellahToAttach.getClass(), creditFellahListCreditFellahToAttach.getIdcredit());
                attachedCreditFellahList.add(creditFellahListCreditFellahToAttach);
            }
            fellah.setCreditFellahList(attachedCreditFellahList);
            em.persist(fellah);
            for (Depot depotListDepot : fellah.getDepotList()) {
                Fellah oldIdFellahOfDepotListDepot = depotListDepot.getIdFellah();
                depotListDepot.setIdFellah(fellah);
                depotListDepot = em.merge(depotListDepot);
                if (oldIdFellahOfDepotListDepot != null) {
                    oldIdFellahOfDepotListDepot.getDepotList().remove(depotListDepot);
                    oldIdFellahOfDepotListDepot = em.merge(oldIdFellahOfDepotListDepot);
                }
            }
            for (CreditFellah creditFellahListCreditFellah : fellah.getCreditFellahList()) {
                Fellah oldIdFellahOfCreditFellahListCreditFellah = creditFellahListCreditFellah.getIdFellah();
                creditFellahListCreditFellah.setIdFellah(fellah);
                creditFellahListCreditFellah = em.merge(creditFellahListCreditFellah);
                if (oldIdFellahOfCreditFellahListCreditFellah != null) {
                    oldIdFellahOfCreditFellahListCreditFellah.getCreditFellahList().remove(creditFellahListCreditFellah);
                    oldIdFellahOfCreditFellahListCreditFellah = em.merge(oldIdFellahOfCreditFellahListCreditFellah);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Fellah fellah) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Fellah persistentFellah = em.find(Fellah.class, fellah.getIdfellah());
            List<Depot> depotListOld = persistentFellah.getDepotList();
            List<Depot> depotListNew = fellah.getDepotList();
            List<CreditFellah> creditFellahListOld = persistentFellah.getCreditFellahList();
            List<CreditFellah> creditFellahListNew = fellah.getCreditFellahList();
            List<Depot> attachedDepotListNew = new ArrayList<Depot>();
            for (Depot depotListNewDepotToAttach : depotListNew) {
                depotListNewDepotToAttach = em.getReference(depotListNewDepotToAttach.getClass(), depotListNewDepotToAttach.getIddepot());
                attachedDepotListNew.add(depotListNewDepotToAttach);
            }
            depotListNew = attachedDepotListNew;
            fellah.setDepotList(depotListNew);
            List<CreditFellah> attachedCreditFellahListNew = new ArrayList<CreditFellah>();
            for (CreditFellah creditFellahListNewCreditFellahToAttach : creditFellahListNew) {
                creditFellahListNewCreditFellahToAttach = em.getReference(creditFellahListNewCreditFellahToAttach.getClass(), creditFellahListNewCreditFellahToAttach.getIdcredit());
                attachedCreditFellahListNew.add(creditFellahListNewCreditFellahToAttach);
            }
            creditFellahListNew = attachedCreditFellahListNew;
            fellah.setCreditFellahList(creditFellahListNew);
            fellah = em.merge(fellah);
            for (Depot depotListOldDepot : depotListOld) {
                if (!depotListNew.contains(depotListOldDepot)) {
                    depotListOldDepot.setIdFellah(null);
                    depotListOldDepot = em.merge(depotListOldDepot);
                }
            }
            for (Depot depotListNewDepot : depotListNew) {
                if (!depotListOld.contains(depotListNewDepot)) {
                    Fellah oldIdFellahOfDepotListNewDepot = depotListNewDepot.getIdFellah();
                    depotListNewDepot.setIdFellah(fellah);
                    depotListNewDepot = em.merge(depotListNewDepot);
                    if (oldIdFellahOfDepotListNewDepot != null && !oldIdFellahOfDepotListNewDepot.equals(fellah)) {
                        oldIdFellahOfDepotListNewDepot.getDepotList().remove(depotListNewDepot);
                        oldIdFellahOfDepotListNewDepot = em.merge(oldIdFellahOfDepotListNewDepot);
                    }
                }
            }
            for (CreditFellah creditFellahListOldCreditFellah : creditFellahListOld) {
                if (!creditFellahListNew.contains(creditFellahListOldCreditFellah)) {
                    creditFellahListOldCreditFellah.setIdFellah(null);
                    creditFellahListOldCreditFellah = em.merge(creditFellahListOldCreditFellah);
                }
            }
            for (CreditFellah creditFellahListNewCreditFellah : creditFellahListNew) {
                if (!creditFellahListOld.contains(creditFellahListNewCreditFellah)) {
                    Fellah oldIdFellahOfCreditFellahListNewCreditFellah = creditFellahListNewCreditFellah.getIdFellah();
                    creditFellahListNewCreditFellah.setIdFellah(fellah);
                    creditFellahListNewCreditFellah = em.merge(creditFellahListNewCreditFellah);
                    if (oldIdFellahOfCreditFellahListNewCreditFellah != null && !oldIdFellahOfCreditFellahListNewCreditFellah.equals(fellah)) {
                        oldIdFellahOfCreditFellahListNewCreditFellah.getCreditFellahList().remove(creditFellahListNewCreditFellah);
                        oldIdFellahOfCreditFellahListNewCreditFellah = em.merge(oldIdFellahOfCreditFellahListNewCreditFellah);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = fellah.getIdfellah();
                if (findFellah(id) == null) {
                    throw new NonexistentEntityException("The fellah with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Fellah fellah;
            try {
                fellah = em.getReference(Fellah.class, id);
                fellah.getIdfellah();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The fellah with id " + id + " no longer exists.", enfe);
            }
            List<Depot> depotList = fellah.getDepotList();
            for (Depot depotListDepot : depotList) {
                depotListDepot.setIdFellah(null);
                depotListDepot = em.merge(depotListDepot);
            }
            List<CreditFellah> creditFellahList = fellah.getCreditFellahList();
            for (CreditFellah creditFellahListCreditFellah : creditFellahList) {
                creditFellahListCreditFellah.setIdFellah(null);
                creditFellahListCreditFellah = em.merge(creditFellahListCreditFellah);
            }
            em.remove(fellah);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Fellah> findFellahEntities() {
        return findFellahEntities(true, -1, -1);
    }

    public List<Fellah> findFellahEntities(int maxResults, int firstResult) {
        return findFellahEntities(false, maxResults, firstResult);
    }

    private List<Fellah> findFellahEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Fellah.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Fellah findFellah(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Fellah.class, id);
        } finally {
            em.close();
        }
    }

    public int getFellahCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Fellah> rt = cq.from(Fellah.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
